#include "AbstractTreeProxyModel.h"



AbstractTreeProxyModel::AbstractTreeProxyModel(QObject *parent) :
    AbstractItemProxyModel(parent)
{
}



QModelIndex AbstractTreeProxyModel::index(int row, int column, const QModelIndex &parent) const
{
    if (!hasIndex(row, column, parent)) return QModelIndex();

    QModelIndex index = AbstractItemProxyModel::index(row, column, parent);
    if (index.isValid()) return index;

    if (!m_children.contains(parent)) QModelIndex();

    QMapIterator<SourceIndex, ProxyIndex> it(m_children.value(parent));
    while (it.hasNext())
    {
        it.next();
        index = it.value();
        if (index.row() != row || index.column() != column) continue;

        return index;
    }

    return QModelIndex();
}



QModelIndex AbstractTreeProxyModel::parent(const QModelIndex &child) const
{
    if (!child.isValid()) return QModelIndex();

    if (m_indexes.values().contains(child)) return QModelIndex();

    QMapIterator<ProxyIndex, IndexMap> it(m_children);
    while (it.hasNext())
    {
        it.next();
        if (it.value().values().contains(child)) return it.key();
    }

    return QModelIndex();
}

int AbstractTreeProxyModel::rowCount(const QModelIndex &parent) const
{
    if (!parent.isValid()) return AbstractItemProxyModel::rowCount(parent);

    if (!m_children.contains(parent)) return 0;
    return m_children.value(parent).size();
}



QModelIndex AbstractTreeProxyModel::mapFromSource(const QModelIndex &sourceIndex) const
{
    if (!sourceIndex.isValid()) return QModelIndex();

    ProxyIndex proxy = AbstractItemProxyModel::mapFromSource(sourceIndex);
    if (proxy.isValid()) return proxy;

    foreach (IndexMap row, m_children.values())
    {
        if (!row.keys().contains(sourceIndex)) continue;
        return row.value(sourceIndex);
    }

    return QModelIndex();
}



QModelIndex AbstractTreeProxyModel::mapToSource(const QModelIndex &proxyIndex) const
{
    if (!proxyIndex.isValid()) return QModelIndex();

    SourceIndex source = AbstractItemProxyModel::mapToSource(proxyIndex);
    if (source.isValid()) return source;

    foreach (IndexMap row, m_children.values())
    {
        if (!row.values().contains(proxyIndex)) continue;

        return row.key(proxyIndex);
    }

    return QModelIndex();
}



void AbstractTreeProxyModel::addChildMapping(const ProxyIndex& parent, const SourceIndex& source, const ProxyIndex& proxy)
{
    if (!parent.isValid()) return;

    IndexMap indexes;
    if (m_children.contains(parent))
    {
        indexes = m_children.take(parent);
    }

    indexes.insertMulti(source, proxy);
    m_children.insertMulti(parent, indexes);
}



void AbstractTreeProxyModel::clear()
{
    m_children.clear();

    AbstractItemProxyModel::clear();
}


